import { Injectable } from '@angular/core';
import { Http, URLSearchParams } from '@angular/http';
import { HttpErrorResponse } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
import 'rxjs/add/observable/of';

import { Content } from './content';
import { CommitObject } from './commit-object';

@Injectable()
export class BlogService {
  owner = "yorkecao";
  repo = "yorkecao";
  account = "yukun.cao";
  branch = "pages";
  apiPath = "https://gitee.com/api/v5/repos/";
  reposApiPath = this.apiPath + this.owner + "/" + this.repo;
  constructor(
    private http: Http
  ) { }

  markedContent(content: string): Observable<string> {
    return this.http
      .post("https://gitee.com/api/v5/markdown", {
        text: content
      })
      .map(response => response.text());
  }

  isMobile(): boolean {
    if (document.body.offsetWidth < 1000) {
      return true;
    }
    return false;
  }

  getDirs(): Observable<Content[]> {
    let url = this.reposApiPath + "/contents/assets/articles";
    return this.http
      .get(url, {
        params: {
          'ref': 'pages'
        }
      })
      .map(dir => dir.json());
  }

  getFiles(url: string): Observable<Content[]> {
    return this.http
      .get(url, {
        params: {
          'ref': 'pages'
        }
      })
      .map(file => file.json());
  }

  getFile(dir: string, name: string): Promise<string> {
    let url = "http://" + this.owner + ".gitee.io/assets/articles/" + dir + "/" + name;
    // let url = "https://raw.githubusercontent.com/YorkeCao/YorkeCao.github.io/master/assets/articles/Spring Cloud/" + name;
    return this.http
      .get(url)
      .toPromise()
      .then(response => response.text())
      .catch((err: HttpErrorResponse) => {
        if (err.error instanceof Error) {
          return Observable.of<string>(err.error.message).toPromise();
        } else if (err.status == 0) {
          return Observable.of<string>("出错了！").toPromise();
        } else {
          return Observable.of<string>(err.status + " " + err.statusText).toPromise();
        }
      });
  }

  getCommits(): Observable<CommitObject[]> {
    let url = this.reposApiPath + "/commits";
    return this.http
      .get(url)
      .map(commit => commit.json());
  }

  getIssues(page: number, perPage: number): Observable<any[]> {
    let url = this.reposApiPath + "/issues";
    return this.http
      .get(url, {
        params: {
          'state': 'all',
          'sort': 'created',
          'direction': 'desc',
          'page': page,
          'per_page': perPage,
          'creator': this.account
        }
      })
      .map(issue => issue.json());
  }

  getRepo(): Observable<any> {
    const url = this.reposApiPath;
    return this.http
      .get(url)
      .map(repo => repo.json());
  }

  getAbout(): Observable<string> {
    let url = "http://" + this.owner + ".gitee.io/README.md";
    return this.http
      .get(url)
      .map(about => about.text());
  }

  getFileContent(path: string): Observable<any> {
    let url = this.reposApiPath + "/contents/assets/articles" + path;
    return this.http
      .get(url, {
        params: {
          access_token: sessionStorage.getItem('access_token'),
          ref: this.branch
        }
      })
      .map(response => response.json());
  }

  // 创建博文
  createFile(dir: string, file: string): Observable<any> {
    let url = this.reposApiPath + "/contents/assets/articles/" + dir + "/" + file + ".md";
    let body = {
      access_token: sessionStorage.getItem('access_token'),
      branch: this.branch,
      content: this.b64EncodeUnicode('### ' + file),
      message: ':memo: create ' + file
    };
    return this.http
      .post(url, body)
      .map(response => response.json());
  }

  deleleFile(fileContent: any): Observable<any> {
    let url = this.reposApiPath + "/contents/" + fileContent.path;
    return this.http
      .delete(url, {
        params: {
          access_token: sessionStorage.getItem('access_token'),
          sha: fileContent.sha,
          message: ':memo: delete ' + fileContent.name,
          branch: this.branch
        }
      })
  }

  // 更改博文
  updateFile(fileContent: any, content: string): Observable<any> {
    let url = this.reposApiPath + "/contents/" + fileContent.path;
    let body = {
      access_token: sessionStorage.getItem('access_token'),
      branch: this.branch,
      content: this.b64EncodeUnicode(content),
      message: ':memo: update ' + fileContent.name,
      sha: fileContent.sha
    };
    return this.http
      .put(url, body)
      .map(response => response.json());
  }

  // 将字符串编码为 base64
  b64EncodeUnicode(str): string {
    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
      function toSolidBytes(match, p1) {
        return String.fromCharCode(Number('0x' + p1));
    }));
  }
}
